package day18;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Arrays;
//反射Student类里的所有信息
public class Test2_Student {
    public static void main(String[] args) throws Exception {
        //1,获取Student类的Class对象
        Class s = Student.class;
//        method(s);//解析 构造方法
//        method2(s);//解析 成员变量
//        method3(s);//解析 成员方法
//        method4(s);//用反射 创建对象
//        method5(s);//用反射 设置变量的值
        method6(s);//用反射 执行方法
    }
    //用反射 执行方法
    public static void method6(Class s) throws Exception {
        //获取指定的方法 public void test(int a)
        Method m = s.getMethod("test", int.class);
        Object o = s.newInstance();
        //invoke(m,n)--m是对象--n是要给方法传入的参
        m.invoke(o,50);//执行方法
    }
    //用反射 设置变量的值
    public static void method5(Class s) throws Exception {
        //TODO  public String name ;
        Field f = s.getField("name");

        Object o = s.newInstance();
        //set(m,n)--m是对象--n是想要设置啥值
        f.set(o,"jack");//设置值
        System.out.println( f.get(o) );//获取值
    }
    //用反射 创建对象
    public static void method4(Class s) throws Exception{
        //用反射new --自动调用无参构造
        Object o = s.newInstance();
        Student s2 = (Student) o ;//向下转型,目的是使用子类的特有功能
        s2.show();//使用了Student类里功能
    }
    //解析Student.class文件中的 成员方法
    //getMethods() getMethod() -- 获取自己和父类的所有  公开的方法
    public static void method3(Class s) throws NoSuchMethodException {
        //获取 所有方法
        Method[] ms = s.getMethods();
        //遍历数组,获取每个方法m
        for (Method m : ms) {
            System.out.println( m.getName() );//获取方法名
            Class[] c = m.getParameterTypes();//获取参数类型
            System.out.println( Arrays.toString(c) );
        }
        //TODO 获取 特定的方法 public void test(int a)
        Method m = s.getMethod("test", int.class);
        System.out.println( m.getName() );
    }
    //解析Student.class文件中的 成员变量
    //getFields() getField() --获取公开的
    public static void method2(Class s) throws Exception {
        //获取所有 成员变量们~~~~
        Field[] fs = s.getFields();
        //遍历,得到每个成员变量f
        for (Field f : fs) {
            //获取变量名
            System.out.println( f.getName() );
            //获取变量类型
            System.out.println( f.getType().getName() );
        }
        //根据属性名获取属性
        Field f = s.getField("age") ;
        //获取属性类型
        System.out.println( f.getType().getName() );//int?
    }
    //解析Student.class文件中的构造方法
    //getConstructors() getConstructor()--获取公开的
    public static void method(Class s) throws NoSuchMethodException {
        //获取 所有的构造方法 存入Constructor[]
        Constructor[] cs = s.getConstructors();
        //遍历数组,得到每个构造方法c
        for (Constructor c : cs) {
            //获取构造方法的 名称
            System.out.println(c.getName());
            //TODO 解析构造方法的 参数的类型
            Class[] cc = c.getParameterTypes();
            System.out.println(Arrays.toString(cc));
        }
//TODO 获取指定的构造方法 --public Student(int age)
//getConstructor()的参数是 构造方法的参数类型 的Class对象
        Constructor con = s.getConstructor(int.class);
        System.out.println( con.getName()+"~~~" );
    }
}
